#include "Minimization.h"
#include
#include
#include
#include
#include
/* Nasty global variables to store pointers to Java environment
and methods so that we can use them in different parts of this
C code. */
JNIEnv *globalJavaEnv;
jobject globaljavaobject;
jmethodID globalConfunID;
jmethodID globalObjfunID;
/* This routine has the interface required by NAG routine e04ucf for
argument confun. It makes calls back to the Java version of confun */
void confunFun(int *mode, int *ncnln, int *n,
int *ldcj, int needc[], double x[], double c[],
double cjac[], int *nstate, int iuser[], double user[])
{
int i;
int *jneedcpt;
double *jxpt, *jcpt, *jcjacpt;
/* First create some Java arrays to pass to confun */
jintArray jneedc = (*globalJavaEnv)->NewIntArray(globalJavaEnv, *ncnln);
jdoubleArray jx = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, *n);
jdoubleArray jc = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, *ncnln);
jdoubleArray jcjac = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, ((*ldcj)*(*n)));
/* Copy input arguments to Java arrays needc and x */
jneedcpt = (*globalJavaEnv)->GetIntArrayElements(globalJavaEnv, jneedc, 0);
jxpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jx, 0);
for (i = 0; i < *ncnln; i++)
jneedcpt[i] = needc[i];
for (i = 0; i < *n; i++)
jxpt[i] = x[i];
/* Release array elements back to Java (this puts the values
back into Java arrays jneedc and jx) */
(*globalJavaEnv)->ReleaseIntArrayElements(globalJavaEnv, jneedc, jneedcpt, 0);
(*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jx, jxpt, 0);
/* Call the Java method via its method ID */
(*globalJavaEnv)->CallVoidMethod(globalJavaEnv, globaljavaobject,
globalConfunID, (jint)(*mode),
(jint) (*ncnln), (jint)(*n),
(jint)(*ldcj), jneedc, jx, jc,
jcjac, (jint)(*nstate));
/* Copy results from Java arrays back to C arrays */
jcpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jc, 0);
jcjacpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jcjac, 0);
for (i = 0; i < *ncnln; i++)
c[i] = jcpt[i];
for (i = 0; i < (*ldcj)*(*n); i++)
cjac[i] = jcjacpt[i];
/* Release array elements back to Java to free memory */
(*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jc, jcpt, 0);
(*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jcjac, jcjacpt, 0);
}
/* This routine has the interface required by NAG routine e04ucf for
argument objfun. It makes calls back to the Java version of objfun */
void objfunFun(int *mode, int *n, double x[], double *objf, double objgrd[],
int *nstate, int iuser[], double user[])
{
int i;
double *jobjgrdpt;
/* First create some Java arrays to pass to objfun */
jdoubleArray jx = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, *n);
jdoubleArray jobjgrd = (*globalJavaEnv)->NewDoubleArray(globalJavaEnv, *n);
/* Copy input array x to Java array jx */
double *jxpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv, jx, 0);
for (i = 0; i < *n; i++)
jxpt[i] = x[i];
/* Release array elements back to Java (this puts the values into jx) */
(*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jx, jxpt, 0);
/* Call Java objfun which fills in array objgrd and returns objf */
*objf = (*globalJavaEnv)->CallDoubleMethod(globalJavaEnv, globaljavaobject,
globalObjfunID, (jint) (*mode),
(jint) (*n), jx, jobjgrd,
(jint) (*nstate));
/* Get results back from Java to C array objgrd */
jobjgrdpt = (*globalJavaEnv)->GetDoubleArrayElements(globalJavaEnv,
jobjgrd, 0);
for (i = 0; i < *n; i++)
objgrd[i] = jobjgrdpt[i];
/* Release array elements back to Java to free memory */
(*globalJavaEnv)->ReleaseDoubleArrayElements(globalJavaEnv, jobjgrd,
jobjgrdpt, 0);
}
JNIEXPORT jint JNICALL Java_Minimization_e04ucf
(
JNIEnv *env,
jobject object,
jint n,
jint nclin,
jint ncnln,
jdoubleArray a,
jint lda,
jdoubleArray bl,
jdoubleArray bu,
jstring confun,
jstring objfun,
jdoubleArray objf,
jdoubleArray objgrd,
jdoubleArray x
)
{
/* Local variables and arrays */
int ldcj;
int ldr;
int iter;
int *istate;
double *c;
double *cjac;
double *clamda;
double *r;
int liwork;
int *iwork;
int lwork;
double *work;
int ifail;
/* N.B. we choose not to use iuser and user arrays in our evaluation
functions, so these are empty arrays. */
int iuser[1];
double user[1];
jclass cls;
const char *confunction;
const char *objfunction;
jdouble *a_pt, *bl_pt, *bu_pt, *x_pt, *objf_pt, *objgrd_pt;
/* Array leading dimension information required by the Fortran routine */
if (ncnln > 0)
ldcj = ncnln;
else
ldcj = 1;
ldr = n;
/* Compute the amount of workspace we need to supply to e04ucf */
liwork = 3 * n + nclin + 2 * ncnln;
if (ncnln == 0 && nclin == 0)
lwork = 20 * n;
else if (ncnln == 0 && nclin > 0)
lwork = 2 * n*n + 20 * n + 11 * nclin;
else
lwork = 2 * n*n + n*nclin + 2*n*ncnln + 20*n + 11*nclin + 21*ncnln;
/* Allocate arrays of appropriate size. */
/* Note that we store cjac as a one dimensional array rather than
a 2D array as in Fortran, for convenience in communication with
Java. */
istate = (int *)malloc((n+nclin+ncnln)*sizeof(int));
c = (double *)malloc((ncnln)*sizeof(double));
cjac = (double *)malloc((ldcj*n)*sizeof(double));
clamda = (double *)malloc((n+nclin+ncnln)*sizeof(double));
r = (double *)malloc((ldr*n)*sizeof(double));
iwork = (int *)malloc((liwork)*sizeof(int));
work = (double *)malloc((lwork)*sizeof(double));
/* Copy the Java env pointers to global space
so that confunFun and objfunFun can access them. */
globalJavaEnv = env;
globaljavaobject = object;
/* Get hold of the name of the user's Java evaluation functions. */
confunction = (*env)->GetStringUTFChars(env, confun, 0);
objfunction = (*env)->GetStringUTFChars(env, objfun, 0);
/* Now we have the Java evaluation function names we can use
them to get hold of handles (method IDs) to the functions.
Once more, the method IDs are stored globally so that confunFun
and objfunFun can use them. Note that the Java function signatures
must be correct. You can find out the signatures after compiling
the Java program Minimization.java by using the command
% javap -private -s Minimization
*/
cls = (*env)->GetObjectClass(env, object);
globalConfunID = (*env)->GetMethodID(env, cls, confunction, "(IIII[I[D[D[DI)V");
globalObjfunID = (*env)->GetMethodID(env, cls, objfunction, "(II[D[DI)D");
/* Free up the Java string argument so we don't leak memory. */
(*env)->ReleaseStringUTFChars(env, confun, confunction);
(*env)->ReleaseStringUTFChars(env, objfun, objfunction);
if (globalConfunID == 0)
{
printf("Cannot find confun method \"%s\" with signature \"(IIII[I[D[D[DI)V\"\n",
confunction);
return -1;
}
if (globalObjfunID == 0)
{
printf("Cannot find objfun method \"%s\" with signature \"(II[D[DI)D\"\n",
objfunction);
return -1;
}
/* Extract the arrays from Java */
a_pt = (*env)->GetDoubleArrayElements(env, a, 0);
bl_pt = (*env)->GetDoubleArrayElements(env, bl, 0);
bu_pt = (*env)->GetDoubleArrayElements(env, bu, 0);
objf_pt = (*env)->GetDoubleArrayElements(env, objf, 0);
objgrd_pt = (*env)->GetDoubleArrayElements(env, objgrd, 0);
x_pt = (*env)->GetDoubleArrayElements(env, x, 0);
/* Call to main NAG Library routine e04ucf */
ifail = -1;
#ifdef WINDOWS
E04UCF
#else
e04ucf_
#endif
(&n, &nclin, &ncnln, &lda, &ldcj, &ldr, a_pt, bl_pt, bu_pt,
confunFun, objfunFun, &iter, istate, c, cjac, clamda,
objf_pt, objgrd_pt, r, x_pt, iwork, &liwork, work, &lwork,
iuser, user, &ifail);
/* Release the array elements back to Java and free memory. */
(*env)->ReleaseDoubleArrayElements(env, a, a_pt, 0);
(*env)->ReleaseDoubleArrayElements(env, bl, bl_pt, 0);
(*env)->ReleaseDoubleArrayElements(env, bu, bu_pt, 0);
(*env)->ReleaseDoubleArrayElements(env, objf, objf_pt, 0);
(*env)->ReleaseDoubleArrayElements(env, objgrd, objgrd_pt, 0);
(*env)->ReleaseDoubleArrayElements(env, x, x_pt, 0);
return ifail;
}
// Interface to option setting routine e04uef
JNIEXPORT void JNICALL Java_Minimization_e04uef
(JNIEnv *env, jobject object, jstring option)
{
const char *coption;
/* Get hold of the Java option string. */
coption = (*env)->GetStringUTFChars(env, option, 0);
/* Call the option setting routine */
#ifdef WINDOWS
E04UEF(coption, strlen(coption));
#else
e04uef_(coption, strlen(coption));
#endif
/* Free up the Java string argument so we don't leak memory. */
(*env)->ReleaseStringUTFChars(env, option, coption);
}